package com.cloudbroker.bcs.platform.ltb.middle.util;

import com.cloudbroker.bcs.common.configure.ConfigUtil;
import com.cloudbroker.bcs.common.util.HSBCSProperties;
import com.cloudbroker.bcs.platform.ltb.common.config.ConfigValues;
import com.hundsun.jres.common.util.StringUtils;
import com.pingplusplus.Pingpp;
import com.pingplusplus.exception.*;
import com.pingplusplus.model.Charge;
import com.pingplusplus.model.Refund;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.security.*;
import java.security.spec.X509EncodedKeySpec;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by lili19289 on 2016/12/20.
 */
public class PingPlusUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(PingPlusUtil.class);

//    static {
//        // 设置 API Key
//        Pingpp.apiKey = ConfigUtil.getString("pingplus.secret.key");
//        Pingpp.privateKey=ConfigUtil.getString("pingplus.private.key");
//    }

    public static void setApiKey(){
        if(org.apache.commons.lang.StringUtils.isBlank(Pingpp.apiKey)){
            Pingpp.apiKey = ConfigUtil.getString("pingplus.secret.key");
        }
    }

    public static void setPrivateKey(){
        if(org.apache.commons.lang.StringUtils.isBlank(Pingpp.privateKey)){
            Pingpp.privateKey = ConfigUtil.getString("pingplus.private.key");
        }
    }


    /**
     * 创建 Charge (微信公众号)
     *
     * 创建 Charge 用户�?要组装一�? map 对象作为参数传�?�给 Charge.create();
     * map 里面参数的具体说明请参�?�：https://www.pingxx.com/api#api-c-new
     * @return Charge
     */
    public static Charge createCharge(Map<String, Object> paramMap) throws Exception {
//        Pingpp.apiKey = ConfigUtil.getString("pingplus.secret.key");
//        Pingpp.privateKey=ConfigUtil.getString("pingplus.private.key");
        setApiKey();
        setPrivateKey();
        Charge charge = null;
        Map<String, Object> extra = new HashMap<String, Object>();
        if("wx_pub".equals(paramMap.get("channel").toString())) {
            extra.put("open_id", paramMap.get("open_id"));// 用户在商户微信公众号下的唯一标识，获取方式可参�?? WxPubOAuthExample.java
        }
        paramMap.remove("open_id");
        if("alipay_pc_direct".equals(paramMap.get("channel").toString())){
            extra.put("success_url",ConfigUtil.getString("pingplus.webhooks.callback"));
        }
        Map<String, Object> chargeMap = new HashMap<String, Object>(paramMap);
//        chargeMap.put("order_no",  paramMap.get("order_no"));// 推荐使用 8-20 位，要求数字或字母，不允许其他字�?
        Map<String, String> app = new HashMap<String, String>();
        app.put("id", ConfigUtil.getString("pingplus.appId"));
        chargeMap.put("app", app);
        chargeMap.put("extra", extra);
        try {
            //发起交易请求
            charge = Charge.create(chargeMap);
            // 传到客户端请先转成字符串 .toString(), 调该方法，会自动转成正确�? JSON 字符�?
            String chargeString = charge.toString();
            System.out.println(chargeString);
        } catch (PingppException e) {
            e.printStackTrace();
            LOGGER.error("Ping++请求出错：",e);
            throw e;

        }
        return charge;
    }

    public static  Charge retrieve(String id) {
        Charge charge = null;
        try {
            Map<String, Object> params = new HashMap<String, Object>();
            charge = Charge.retrieve(id, params);
            System.out.println(charge);
        } catch (PingppException e) {
            e.printStackTrace();
        }

        return charge;
    }

    public static Refund refund(String chargeId,Map<String, Object> paramMap) throws  PingppException {
        if (paramMap.isEmpty()) {
            return null;
        }
        setApiKey();
        setPrivateKey();
        Refund refund = null;
        try {
            refund = Refund.create(chargeId, paramMap);
            System.out.println(refund);
        } catch (PingppException e) {
            e.printStackTrace();
            LOGGER.error("Ping++退款出错：",e);
            throw e;
        }
        return refund;
    }

    public static PublicKey getPubKey() throws Exception {
        String pubKeyString = ConfigUtil.getString("pingplus.pub.key");
        pubKeyString = pubKeyString.replaceAll("(-+BEGIN PUBLIC KEY-+\\r?\\n|-+END PUBLIC KEY-+\\r?\\n?)", "");
        byte[] keyBytes = Base64.decodeBase64(pubKeyString);

        // generate public key
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(spec);
        return publicKey;
    }

    public static boolean verifyData(String dataString, String signatureString) {
        try {
            PublicKey publicKey = getPubKey();
            byte[] signatureBytes = Base64.decodeBase64(signatureString);
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initVerify(publicKey);
            signature.update(dataString.getBytes("UTF-8"));
            return signature.verify(signatureBytes);
        }catch (SignatureException e){
            LOGGER.error("签名出现错误",e);
        }catch (Exception e){
            LOGGER.error("签名验证出现错误",e);
        }
        return false;
    }


    public static void main(String[] args) throws Exception{
        Map<String, Object> chargeMap = new HashMap<String, Object>();
        chargeMap.put("amount", 100);//订单总金�?, 人民币单位：分（如订单�?�金额为 1 元，此处请填 100�?
        chargeMap.put("currency", "cny");
        chargeMap.put("subject", "Your Subject");
        chargeMap.put("body", "Your Body");
        String orderNo = new Date().getTime() + StringUtils.randomString(7);
        chargeMap.put("order_no", "1482385112974z8QdD8G");// 推荐使用 8-20 位，要求数字或字母，不允许其他字�?
        chargeMap.put("channel", "wx");// 支付使用的第三方支付渠道取�?�，请参考：https://www.pingxx.com/api#api-c-new
        chargeMap.put("client_ip", "127.0.0.1"); // 发起支付请求客户端的 IP 地址，格式为 IPV4，如: 127.0.0.1
        Charge charge = createCharge(chargeMap);

        //id ch_9SefnTr5SqrLOqrTW1i1mHG4 过几个小时看看是否过期

        Charge charge1 = retrieve(charge.getId());
    }

}
